﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;

namespace FlexiPay
{
    public partial class RuleDefinition : System.Web.UI.Page
    {
        #region screen enable/disable/load

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                ManageEditable(false);
            }
        }

        protected void ManageEditable(bool editable)
        {
            PanelMiddle.Enabled = editable;
            PanelUpper.Enabled = editable;
            //manage buttons
            BApply.Visible = editable;
            BCancel.Visible = editable;
            BEdit.Visible = !editable;
            BCreate.Visible = !editable;
            LBAllRules.Enabled = editable;
            LBSelected.Enabled = editable;

            //disable the subrule control
            if (editable)
            {
                LBAllRules.Attributes.Remove("disabled");
                LBSelected.Attributes.Remove("disabled");
            }
            else
            {
                LBAllRules.Attributes.Add("disabled", "");
                LBSelected.Attributes.Add("disabled", "");
            }
        }

        protected void DDLFrequency_Load(object sender, EventArgs e)
        {
            for (int i = 1; i <= 31; i++)
            {
                DDLFrequency.Items.Add(new ListItem(i.ToString(), i.ToString()));
            }
            if (!IsPostBack)
                DDLFrequency.SelectedIndex = 0;
        }

        protected void CBRepeats_CheckedChanged(object sender, EventArgs e)
        {
            DDLFrequency.Enabled = !DDLFrequency.Enabled;
            DDLFreqType.Enabled = !DDLFreqType.Enabled;
        }

        #endregion

        #region buttons at work
        protected void BCancel_Click(object sender, EventArgs e)
        {
            ManageEditable(false);
            loadRule2Panel(Convert.ToInt32(LBRule.SelectedValue.ToString()));
        }

        protected void BEdit_Click(object sender, EventArgs e)
        {
            ManageEditable(true);
        }

        protected void BCreate_Click(object sender, EventArgs e)
        {
            ViewState["SelectedRule"] = null;
            ManageEditable(true);
            LoadDefaultRule2Panel();
        }

        protected void BApply_Click(object sender, EventArgs e)
        {
            if (LBSelected.Items.Count <= 0)
            {
                WebMsgBox.Show("Please select atleast 1 SubRule.");
                return;
            }
            if (!dateValidation(TBFrom.Text, TBToDate.Text))
            {
                return;
            }

                        
            ManageEditable(false);
            if (ViewState["SelectedRule"] == null)
            {
                int RuleId = InsertRule();
                InsertSubRules(RuleId);
                InsertCycles(RuleId);
                LBRule.DataBind();
                LBRule.SelectedValue = RuleId.ToString();
                loadRule2Panel(RuleId);
            }
            else
            {
                int RuleId = Convert.ToInt32(LBRule.SelectedValue.ToString());
                UpdateRule(RuleId);
                InsertSubRules(RuleId);
                InsertCycles(RuleId);
                LBRule.SelectedValue = RuleId.ToString();
                LBRule.DataBind();
                //loadRule2Panel(RuleId);
            }
        }

        private bool dateValidation(string from, string to)
        {
            try
            {
                DateTime fromD = Convert.ToDateTime(from);
                DateTime toD = Convert.ToDateTime(to);

                if (fromD >= toD)
                {
                    WebMsgBox.Show("FROM Date should be less than TO Date.");
                    return false;
                }
            }
            catch (Exception)
            {
                WebMsgBox.Show("Please enter a valid date.");
                return false;
            }

            return true;
        }

        #endregion

        #region DB operations
        private void InsertCycles(int RuleId)
        {
            DateTime start = Convert.ToDateTime(TBFrom.Text);
            DateTime end = Convert.ToDateTime(TBToDate.Text);

            if (CBRepeats.Checked)
            {
                string frequencyType = DDLFreqType.SelectedValue.ToString();
                int frequency = Convert.ToInt32(DDLFrequency.SelectedValue.ToString());

                DateTime current = start;
                DateTime next = getNextCycle(current, frequencyType, frequency);

                //delete old entries before inserting new
                string deleteq = "DELETE FROM CycleStatus WHERE RuleId='" + RuleId.ToString() + "'";
                DataBaseMethods.ExecuteNonQuery(deleteq);

                string insertq = "INSERT INTO CycleStatus(RuleId, CycleId, StartDate, EndDate, Status) VALUES ('" + RuleId.ToString() + "'";
                int count = 0;
                while (next <= end)
                {
                    string query = insertq;
                    query += ",'" + count.ToString() + "','" + current.ToString("yyyy-MM-dd") + "','" + next.ToString("yyyy-MM-dd") + "','Unbilled' )";
                    DataBaseMethods.ExecuteNonQuery(query);

                    count = count + 1; current = next.AddDays(1);
                    next = getNextCycle(current, frequencyType, frequency);
                }
            }
            else
            {
                //delete old entries before inserting new
                string deleteq = "DELETE FROM CycleStatus WHERE RuleId='" + RuleId.ToString() + "'";
                DataBaseMethods.ExecuteNonQuery(deleteq);

                string insertq = "INSERT INTO CycleStatus(RuleId, CycleId, StartDate, EndDate, Status) VALUES ('" + RuleId.ToString() + "'";
                insertq += ",'0','" + start.ToString("yyyy-MM-dd") + "','" + end.ToString("yyyy-MM-dd") + "','Unbilled' )";
                DataBaseMethods.ExecuteNonQuery(insertq);
            }
        }

        private DateTime getNextCycle(DateTime current, string type, int count)
        {
            DateTime daten = new DateTime();
            if (type == "Days")
                daten = current.AddDays(count).AddDays(-1);
            else if (type == "Weeks")
                daten = current.AddDays(7 * count).AddDays(-1);
            else if (type == "Month")
                daten = current.AddMonths(count).AddDays(-1);
            else
                daten = current.AddYears(count).AddDays(-1);
            return daten;
        }

        private void InsertSubRules(int RuleId)
        {
            string query = "DELETE FROM RuleRelations WHERE RuleID='" + RuleId.ToString() + "'";
            DataBaseMethods.ExecuteNonQuery(query);

            //check if empty - delete all and done, else carry on with insert
            if (LBSelected.Items.Count == 0) return;

            //insert query
            string insert = "INSERT INTO RuleRelations (RuleId, SubRuleId, Priority) VALUES ('" + RuleId.ToString() + "'";

            for (int i = 0; i < LBSelected.Items.Count; i++)
            {
                string current_insert = insert;
                current_insert += ",'" + LBSelected.Items[i].Value.ToString() + "','" + i.ToString() + "')";
                DataBaseMethods.ExecuteNonQuery(current_insert);
            }

        }

        private int InsertRule()
        {
            //define query
            string insertQuery;
            if (CBRepeats.Checked)
                insertQuery = "INSERT INTO RuleDetails(RuleName,ProductName,RuleType,FromDate,ToDate,Repeats,DMY,DMYCount,RuleStatus,CreatedBy,CreatedOn)";
            else
                insertQuery = "INSERT INTO RuleDetails(RuleName,ProductName,RuleType,FromDate,ToDate,Repeats,RuleStatus,CreatedBy,CreatedOn)";
            //define values
            insertQuery += " VALUES ( '" + TBRuleName.Text + "','" + Session["ProductName"].ToString() + "','" + DDLType.SelectedValue.ToString() + "','";
            insertQuery += Convert.ToDateTime(TBFrom.Text).ToString("yyyy-MM-dd") + "','";
            insertQuery += Convert.ToDateTime(TBToDate.Text).ToString("yyyy-MM-dd") + "','";
            insertQuery += CBRepeats.Checked.ToString() + "','";
            if (CBRepeats.Checked)
                insertQuery += DDLFreqType.SelectedValue.ToString() + "','" + DDLFrequency.SelectedValue.ToString() + "','";
            insertQuery += DDLStatus.SelectedValue.ToString() + "','" + Session["loginId"].ToString() + "','" + DateTime.Now.ToString("yyyy-MM-dd") + "' )";
            insertQuery += " SET @RuleId = SCOPE_IDENTITY()";
            //perform query
            int RuleId = DataBaseMethods.ExecuteIdentityInsert(insertQuery, "RuleId");
            return RuleId;
        }

        private void UpdateRule(int RuleId)
        {
            //generate query
            string updateQuery = "UPDATE [RuleDetails] SET ";
            updateQuery += "RuleName = '" + TBRuleName.Text + "'";
            updateQuery += ", RuleType = '" + DDLType.SelectedValue.ToString() + "'";
            updateQuery += ", FromDate = '" + Convert.ToDateTime(TBFrom.Text).ToString("yyyy-MM-dd") + "'";
            updateQuery += ", ToDate = '" + Convert.ToDateTime(TBToDate.Text).ToString("yyyy-MM-dd") + "'";
            updateQuery += ", Repeats ='" + CBRepeats.Checked.ToString() + "'";
            if (CBRepeats.Checked)
            {
                updateQuery += ", DMY = '" + DDLFreqType.SelectedValue.ToString() + "'";
                updateQuery += ", DMYCount = '" + DDLFrequency.SelectedValue.ToString() + "'";
            }
            updateQuery += ", RuleStatus = '" + DDLStatus.SelectedValue.ToString() + "'";
            updateQuery += ", CreatedBy = '" + Session["loginId"].ToString() + "'";
            updateQuery += ", CreatedOn = '" + DateTime.Now.ToString("yyyy-MM-dd") + "'";
            updateQuery += "WHERE RuleId = '" + RuleId.ToString() + "'";

            //perform operation
            int NoOfRows = DataBaseMethods.ExecuteNonQuery(updateQuery);
            if (NoOfRows != 1)
                throw new Exception("Error while updating RuleDetails table. Rule Id not found - " + RuleId.ToString() + ".");
            return;
        }
        #endregion

        #region update display as per selected rule
        protected void DDLFreqType_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        protected void LBRule_DataBound(object sender, EventArgs e)
        {
            if (!IsPostBack || LBRule.SelectedIndex < 0)
                return; 
            //    LBRule.SelectedIndex = 0;
            loadRule2Panel(Convert.ToInt32(LBRule.SelectedValue.ToString()));
        }

        protected void LBRule_SelectedIndexChanged(object sender, EventArgs e)
        {
            loadRule2Panel(Convert.ToInt32(LBRule.SelectedValue.ToString()));
            ManageEditable(false);
        }

        void LoadDefaultRule2Panel()
        {
            TBRuleName.Text = "Untitled_" + DateTime.Now.ToString("yyyyMMdd_HHmmss");
            DDLType.SelectedIndex = 0; //basic
            TBFrom.Text = DateTime.Now.ToString("dd-MMM-yyyy");
            TBToDate.Text = DateTime.Now.AddYears(1).ToString("dd-MMM-yyyy");
            CBRepeats.Checked = true;
            DDLFreqType.SelectedIndex = 2; //months
            DDLFrequency.SelectedIndex = 0; // one
            DDLStatus.SelectedIndex = 0; //approved
            LBSelected.Items.Clear();
        }

        void loadRule2Panel(int RuleId)
        {
            ViewState["SelectedRule"] = RuleId.ToString(); ;
            string select = "select [RuleName],[RuleType],[FromDate],[ToDate],[Repeats],[DMY],[DMYCount],[RuleStatus] ";
            select += " From [RuleDetails] where [RuleId] = '" + RuleId.ToString() + "'";

            //load rule details to upper panel
            DataTable dt = DataBaseMethods.ExecuteSelectQuery(select);
            TBRuleName.Text = dt.Rows[0][0].ToString();
            DDLType.SelectedValue = dt.Rows[0][1].ToString();
            TBFrom.Text = Convert.ToDateTime(dt.Rows[0][2].ToString()).ToString("dd-MMM-yyyy");
            TBToDate.Text = Convert.ToDateTime(dt.Rows[0][3].ToString()).ToString("dd-MMM-yyyy");
            CBRepeats.Checked = Convert.ToBoolean(dt.Rows[0][4].ToString());
            if (CBRepeats.Checked)
            {
                DDLFreqType.SelectedValue = dt.Rows[0][5].ToString();
                DDLFrequency.SelectedValue = dt.Rows[0][6].ToString();
            }
            DDLStatus.SelectedValue = dt.Rows[0][7].ToString();

            //load selected rules
            LBSelected.DataBind();
        }
        #endregion

        #region arrow buttons
        protected void IBRight_Click(object sender, ImageClickEventArgs e)
        {
            if (LBAllRules.SelectedIndex < 0) return;
            if (LBSelected.Items.Contains(LBAllRules.SelectedItem)) return;
            LBSelected.Items.Add(LBAllRules.SelectedItem);
            //LBSelected.DataBind();
            LBSelected.ClearSelection();
        }

        protected void IBLeft_Click(object sender, ImageClickEventArgs e)
        {
            if (LBSelected.SelectedIndex < 0) return;
            string id = LBSelected.SelectedValue.ToString();
            LBSelected.Items.Remove(LBSelected.SelectedItem);
            LBSelected.ClearSelection();
            LBAllRules.SelectedValue = id;
            //LBSelected.SelectedIndex = -1;
        }

        protected void IBUp_Click(object sender, ImageClickEventArgs e)
        {
            if (LBSelected.SelectedIndex <= 0) return;
            ListItem li = LBSelected.SelectedItem;
            int index = LBSelected.SelectedIndex;
            LBSelected.Items.Remove(LBSelected.SelectedItem);
            LBSelected.ClearSelection();
            LBSelected.Items.Insert(index - 1, li);
            LBSelected.SelectedIndex = index - 1;
            //LBSelected.a
        }

        protected void IBDown_Click(object sender, ImageClickEventArgs e)
        {
            if (LBSelected.SelectedIndex == (LBSelected.Items.Count - 1)) return;
            ListItem li = LBSelected.SelectedItem;
            int index = LBSelected.SelectedIndex;
            LBSelected.Items.Remove(LBSelected.SelectedItem);
            LBSelected.ClearSelection();
            LBSelected.Items.Insert(index + 1, li);
            LBSelected.SelectedIndex = index + 1;
        }
        #endregion
    }
}